package org.apache.dolphinscheduler.api.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Parameter;
import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
import org.apache.dolphinscheduler.api.dto.AuthDto;
import org.apache.dolphinscheduler.api.exceptions.ApiException;
import org.apache.dolphinscheduler.api.service.RoleService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.dao.entity.Role;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

import static org.apache.dolphinscheduler.api.enums.Status.*;

/**
 * 角色接口
 * @author
 * @date 2023-07-03 09:50
 * @descriprion
 */
@Api(tags = "ROLE_TAG")
@RestController
@RequestMapping("/role")
public class RoleController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(RoleController.class);

    @Autowired
    private RoleService roleService;

    /**
     * query role list paging
     *
     * @param pageNo page number
     * @param searchVal search avlue
     * @param pageSize page size
     * @return role list page
     */
    @ApiOperation(value = "queryRoleList", notes = "QUERY_ROLE_LIST_NOTES")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "PAGE_NO", required = true, dataType = "Int", example = "1"),
            @ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", required = true, dataType = "Int", example = "10"),
            @ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", type = "String")
    })
    @GetMapping(value = "/pageList")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_ROLE_LIST_PAGING_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    public Result queryRoleList(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                                @RequestParam("pageNo") Integer pageNo,
                                @RequestParam("pageSize") Integer pageSize,
                                @RequestParam(value = "searchVal", required = false) String searchVal) {
        Result result = checkPageParams(pageNo, pageSize);
        if (!result.checkResult()) {
            return result;

        }
        searchVal = ParameterUtils.handleEscapes(searchVal);
        result = roleService.queryRoleList(loginUser, searchVal, pageNo, pageSize);
        return result;
    }

    @ApiOperation(value = "listAllRole", notes = "LIST_ALL_ROLE_NOTES")
    @GetMapping(value = "/listAll")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(QUERY_ROLE_LIST_SELECT_ERROR)
    // @PreAuthorize("hasAnyAuthority('system:users:create,system:users:update')")
    public Result listAll() {
        return roleService.listAll();
    }

    @ApiOperation(value = "findRoleUser", notes = "FIND_ROLE_NOTES")
    @GetMapping(value = "/findUser")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(FIND_ROLE_USER_ERROR)
    // @PreAuthorize("hasAnyAuthority('system:role:users')")
    public Result findRoleUser(@RequestParam(value = "id") int id) throws Exception {
        return roleService.findRoleUser(id);
    }

    @ApiOperation(value = "findRole", notes = "FIND_ROLE_NOTES")
    @GetMapping(value = "/find")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(FIND_ROLE_ERROR)
    // @PreAuthorize("hasAnyAuthority('system:role:update')")
    public Result findRole(@RequestParam(value = "id") int id) throws Exception {
        return roleService.findRole(id);
    }

    @ApiOperation(value = "getPermissions", notes = "GET_ROLE_PERMISSION_NOTES")
    @GetMapping(value = "/getPermissions")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(FIND_ROLE_PERMISSION_ERROR)
    // @PreAuthorize("hasAnyAuthority('system:role:grant')")
    public Result getPermissions(@RequestParam(value = "id") int id) throws Exception {
        return roleService.getPermissions(id);
    }

    @ApiOperation(value = "auth", notes = "AUTH_ROLE_PERMISSION_NOTES")
    @PostMapping(value = "/auth")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(FIND_ROLE_PERMISSION_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    // @PreAuthorize("hasAnyAuthority('system:role:grant')")
    public Result auth(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                       @RequestBody AuthDto authDto) throws Exception {
        Map<String, Object> result = roleService.auth(loginUser, authDto.getId(), authDto.getPermissionIds());
        return returnDataList(result);
    }

    @ApiOperation(value = "createRole", notes = "CREATE_ROLE_NOTES")
    @PostMapping(value = "/create")
    @ResponseStatus(HttpStatus.CREATED)
    @ApiException(CREATE_ROLE_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    // @PreAuthorize("hasAnyAuthority('system:role:create')")
    public Result createRole(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                             @RequestBody Role role) throws Exception {
        Map<String, Object> result = roleService.createRole(loginUser, role);
        return returnDataList(result);
    }

    @ApiOperation(value = "updateRole", notes = "UPDATE_ROLE_NOTES")
    @PostMapping(value = "/update")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(UPDATE_ROLE_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    // @PreAuthorize("hasAnyAuthority('system:role:update')")
    public Result updateRole(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                             @RequestBody Role role) throws Exception {
        Map<String, Object> result = roleService.updateRole(loginUser, role);
        return returnDataList(result);
    }

    @ApiOperation(value = "delUserById", notes = "DELETE_ROLE_BY_ID_NOTES")
    @DeleteMapping(value = "/delete")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(DELETE_ROLE_BY_ID_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    // @PreAuthorize("hasAnyAuthority('system:role:delete')")
    public Result deleteROle(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
                             @RequestParam(value = "id") int id) throws Exception {
        Map<String, Object> result = roleService.deleteRole(loginUser, id);
        return returnDataList(result);
    }


    @ApiOperation(value = "updateRole", notes = "更改用户角色")
    @PostMapping(value = "/update/user")
    @ResponseStatus(HttpStatus.OK)
    @ApiException(UPDATE_ROLE_ERROR)
    @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
    // @PreAuthorize("hasAnyAuthority('system:role:update')")
    public Result updateRoleUser(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, String userIds, Integer roleId) throws Exception {
        Map<String, Object> result = roleService.updateRoleUser(loginUser, userIds, roleId);
        return returnDataList(result);
    }
}
